#include <cassert>
#include <xscript/xitemboolean.h>
#include <xscript/xitemint32.h>
#include <xscript/xitemfloat.h>
#include <xscript/xitemstring.h>
#include <xscript/xitemlist.h>
#include <xscript/xitemdict.h>
#include <astree/xabstractsyntaxtreevalue.h>

XAbstractSyntaxTreeValue::XAbstractSyntaxTreeValue(XTokenPtr inputToken):
    XAbstractSyntaxTree(inputToken) {
    setName(inputToken->getString());
    result = XItem::createFromToken(inputToken);
}

XAbstractSyntaxTreeValue::XAbstractSyntaxTreeValue(XTokenPtr inputToken, std::shared_ptr<XItem> value):
    XAbstractSyntaxTree(inputToken) {
    setName(token->getString());
    result = value;
}

bool XAbstractSyntaxTreeValue::invoke(std::shared_ptr<XVariableTable> table) {
    return !result->asUndefined();
}

std::shared_ptr<XAbstractSyntaxTree> XAbstractSyntaxTreeCreatorValue::create(const XTokenBlock& tokens, uint32_t row, uint32_t col, std::shared_ptr<XAbstractSyntaxTreeBuilder> builder) {
    auto tokenLine = tokens.at(row);
    auto list = tokenLine.tokens;
    if (list.size() <= col) {
        XScriptExecutor::getInstance()->setError(XError::XError_NeedMoreTokenError, list.at(col - 1)->toString());
        return nullptr;
    }

    skipToCol = col + 1;
    return std::make_shared<XAbstractSyntaxTreeValue>(list.at(col), XItem::createFromToken(list.at(col)));
}

bool XAbstractSyntaxTreeCreatorInt::isMatched(const XTokenBlock& tokens, uint32_t row, uint32_t col) {
    if (tokens.size() <= row)
        return false;

    auto set = tokens.at(row);
    if (set.tokens.size() <= col)
        return false;

    if (set.tokens.at(col)->asInteger())
        return true;
    return false;
}

bool XAbstractSyntaxTreeCreatorFloat::isMatched(const XTokenBlock& tokens, uint32_t row, uint32_t col) {
    if (tokens.size() <= row)
        return false;

    auto set = tokens.at(row);
    if (set.tokens.size() <= col)
        return false;

    if (set.tokens.at(col)->asFloat())
        return true;
    return false;
}

bool XAbstractSyntaxTreeCreatorBoolean::isMatched(const XTokenBlock& tokens, uint32_t row, uint32_t col) {
    if (tokens.size() <= row)
        return false;

    auto set = tokens.at(row);
    if (set.tokens.size() <= col)
        return false;

    if (set.tokens.at(col)->asBoolean())
        return true;
    return false;
}

bool XAbstractSyntaxTreeCreatorString::isMatched(const XTokenBlock& tokens, uint32_t row, uint32_t col) {
    if (tokens.size() <= row)
        return false;

    auto set = tokens.at(row);
    if (set.tokens.size() <= col)
        return false;

    if (set.tokens.at(col)->asString())
        return true;
    return false;
}

XAbstractSyntaxTreeList::XAbstractSyntaxTreeList(XTokenPtr inputToken):
    XAbstractSyntaxTree(inputToken) {
    setName(L"List");
}

bool XAbstractSyntaxTreeList::invoke(std::shared_ptr<XVariableTable> table) {
    return true;
}
